package com.infolab.aims.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.infolab.aims.common.PaginationHelper;
import com.infolab.aims.common.QueryHelper;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.domain.Department;
import com.infolab.aims.domain.Vendor;
import com.infolab.aims.domain.VendorAsset;
import com.infolab.aims.domain.asset.AssetModel;
import com.infolab.aims.service.intf.VendorService;

@Service
@Transactional
public class VendorServiceImpl implements VendorService {
	
	Log logger = LogFactory.getLog(getClass());
	@PersistenceContext
	private EntityManager em;
	
	public void createVendor(Vendor vendor)
	{
		vendor.setActive(true);
		
		Vendor newVendor = new Vendor();
		
		vendor.setModifiedBy(vendor.getCreatedBy());
		
		vendor.setDateCreated(new Date());
		
		vendor.setDateModified(new Date());
		
		BeanUtils.copyProperties(vendor,newVendor);
		
		em.persist(newVendor);
		
		vendor.setVendorId(newVendor.getVendorId());
		
	}

	public void updateVendor(Vendor vendor) {
		
//		if(vendor.getSection()==null || vendor.getSection().getSectionId()==null)
//			vendor.setSection(null);
		
		Vendor newVendor = em.find(Vendor.class, vendor.getVendorId());
		
		vendor.setDateModified(new Date());
		
		BeanUtils.copyProperties(vendor,newVendor);
		
		em.merge(newVendor);
	}


	public Vendor getVendor(Integer vendorId) {
		// TODO Auto-generated method stub
		Vendor vendor = em.find(Vendor.class, vendorId);
		Query query = em.createQuery("from VendorAsset where vendorId=:vendorId order by vendorAssetId asc");
		query.setParameter("vendorId", vendorId);
		List vendorAssets = query.getResultList();
		vendor.setVendorAssets(vendorAssets);
		return vendor; 
	}

	public Vendor findVendor(SearchCriteria searchCriteria) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public List<Vendor> findVendors(SearchCriteria searchCriteria) {
		// TODO Auto-generated method stub
		return null;
	}

	public SearchResult searchVendor(
			SearchCriteria searchCriteria) {
		
		if(searchCriteria.getCurPage()==null)
			searchCriteria.setCurPage(1);
		
		VendorPaginationHelper helper = new VendorPaginationHelper();
		
		return helper.getSearchResultFromQueryHelper(em, searchCriteria);
	}
	
	public void deleteVendor(Integer vendorId) {
		
		Query query = em.createQuery("update Vendor set active=0 where vendorId=:vendorId");
		
		query.setParameter("vendorId", vendorId);
		
		query.executeUpdate();
		
	}

	public void deleteVendor(Vendor vendor) {
		vendor.setDateModified(new Date());
		vendor.setActive(false);
		em.merge(vendor);
	}		
	
	public static class VendorPaginationHelper extends PaginationHelper<Vendor> {

		@Override
		public String[] getValidColumnName() {
			return new String[]{"vendorCode","vendorName","active","vendorType"};
		}
		
		@Override
		public String[] getValidSortName() {
			return new String[]{"vendorCode","vendorName","vendorType","section.sectionName","modifiedBy","dateModified"};
		}

		@Override
		public String getDefaultSortName() {
			return "vendorName";
		}
		
		@Override
		public QueryHelper getQueryHelper() {
			QueryHelper queryHelper = new QueryHelper();
			queryHelper.select("select vendor from Vendor vendor");
			return queryHelper;
		}
	}

	public void updateVendorAssets(Vendor vendor) {
		Vendor newVendor = em.find(Vendor.class, vendor.getVendorId());
		List<VendorAsset> vendorAssets = vendor.getVendorAssets();
		if(vendorAssets!=null)
		{
			Iterator<VendorAsset> i = vendorAssets.iterator();
			while(i.hasNext())
			{
				VendorAsset vendorAsset = i.next();
				if(vendor.getVendorId()==null)
					i.remove();
				else if(vendorAsset.isDeleted())
				{
					vendorAsset = em.getReference(VendorAsset.class, vendorAsset.getVendorAssetId());
					em.remove(vendorAsset);
					i.remove();
				}
			}
		}
		newVendor.setVendorAssets(vendorAssets);
		
		em.merge(newVendor);
	}

	public List<AssetModel> findAssetModelsPrice(String assetType,Integer vendorId) {
		Query query = em.createNativeQuery("select AMTB_ASSET_MODEL.ASSETMODELID,ASSETMODELCODE,ASSETMODELNAME,unitprice from AMTB_ASSET_MODEL , (select * from AMTB_VENDOR_ASSET where vendorid=:vendorId) AMTB_VENDOR_ASSET where active=1 and assetType=:assetType and amtb_asset_model.assetmodelid=amtb_vendor_asset.assetmodelid ");
		query.setParameter("vendorId", vendorId);
		query.setParameter("assetType", assetType);
		List list = query.getResultList();
		List<AssetModel> assetModels = new ArrayList<AssetModel>();
		if(list!=null)
		{
			for (int i = 0; i < list.size(); i++) {
				Object[] obj = (Object[]) list.get(i);
				Integer assetModelId = (Integer) obj[0];
				String assetModelCode= (String) obj[1];
				String assetModelName= (String) obj[2];
				
				float unitPrice=0f;
				if(obj[3] instanceof BigDecimal)
					unitPrice = ((BigDecimal) obj[3]).floatValue();
				else if(obj[3] instanceof Double)
					unitPrice = ((Double) obj[3]).floatValue();
				
				AssetModel assetModel = new AssetModel(assetModelId.intValue(),assetModelCode,assetModelName,unitPrice);
				
				assetModel.setAssetType(assetType);
				assetModels.add(assetModel);
			}
		}
		
		return assetModels;
	}
}
